'use strict';

// Define some pseudo module globals
var isPro = require('../libs/debug').isPro;
var isDev = require('../libs/debug').isDev;
var isDbg = require('../libs/debug').isDbg;

//
var crypto = require('crypto');
var User = require('../models/user').User;
var findDeadorAlive = require('../libs/remove').findDeadorAlive;
var userRoles = require('../models/userRoles.json');
var Vcode = require('../libs/vcode');

//--- Configuration inclusions
var allStrategies = require('../controllers/strategies.json');

// This is a custom verification function used for Passports because
// we needed something more powerful than what they provided
exports.verify = function (aId, aStrategy, aUsername, aLoggedIn, aDone, aPassword, aPhone, aVcode) {
  var shasum = crypto.createHash('sha256');
  var digest = null;
  var hashedPassword = null;
  // by ElmerZhang: 对密码做 hash
  if (aPassword) {
    var sum = crypto.createHash('sha256');
    sum.update(aUsername + aPassword);
    hashedPassword = sum.digest('hex');
  }

  if (aStrategy === 'github') {
    // We only keep plaintext ids for GH since that's all we need
    digest = aId;
  } else if (aStrategy === 'steam') {
    // Having these forced secure ids would allow us to do things with the user's
    // account and that is something we DO NOT want to do
    shasum.update(String(aId).replace(/^http:/, 'https:'));
    digest = shasum.digest('hex');
  } else if (aId) {
    // Having these ids would allow us to do things with the user's
    // account and that is something we DO NOT want to do
    shasum.update(String(aId));
    digest = shasum.digest('hex');
  }

  findDeadorAlive(User, { 'auths': digest }, true,
    function (aAlive, aUser, aRemoved) {
      var pos = aUser ? aUser.auths.indexOf(digest) : -1;
      if (aRemoved) {
        aDone(null, false, 'User was removed');

        // Always return if production... allows for testing in dev with or without dbg
        if (isPro) {
          return;
        }
      }

      if (!aUser) {
        User.findOne({ 'name': aUsername }, function (aErr, aUser) {
          // WARNING: No err handling

          if (aUser) {
            if (aLoggedIn) {
              if (allStrategies[aStrategy].readonly) {
                aDone(null, false, 'readonly strategy');
                return;
              } else {
                // Add the new strategy to same account
                // This allows linking multiple external accounts to one of ours
                if (digest) {
                  aUser.auths.push(digest);
                }
                aUser.strategies.push(aStrategy);
                aUser.save(function (aErr, aUser) {
                  aDone(aErr, aUser);
                  return;
                });
              }
            } else if (aUser.password && hashedPassword && aUser.password === hashedPassword) {
              // by ElmerZhang: local 登录成功
              if (!aUser.strategies.includes(aStrategy)) {
                aUser.strategies.push(aStrategy);
              }
              aUser.save(function (aErr, aUser) {
                aDone(aErr, aUser);
                return;
              });
            } else {
              aDone(null, false, 'username is taken');
              return;
            }
          } else {
            // Check for strategy readonly
            if (allStrategies[aStrategy].readonly) {
              aDone(null, false, 'readonly strategy');
              return;
            } else if (!aPhone) {
              // by ElmerZhang: 如果用户不存在，且没有填写电话
              aDone(null, false, 'need register');
              return;
            } else {
              // by ElmerZhang: 用户不存在，校验验证码并创建用户
              Vcode.check(aPhone, aVcode).then(success => {
                if (success) {
                  aUser = new User({
                    'name': aUsername,
                    'auths': digest ? [digest] : [],
                    'strategies': [aStrategy],
                    'role': userRoles.length - 2,  // NOTE: Last array element value is system Reserved
                    'about': '',
                    'ghUsername': null,
                    'password': hashedPassword,
                    'phone': aPhone,
                  });
                  aUser.save(function (aErr, aUser) {
                    aDone(aErr, aUser);
                    return;
                  });
                } else {
                  aDone(null, false, 'vcode error');
                }
              });
            }
          }
        });
      } else if (pos > -1 && pos < aUser.auths.length - 1) {
        // Set current strategy to use as default
        aUser.strategies.splice(pos, 1);
        aUser.auths.splice(pos, 1);
        aUser.strategies.push(aStrategy);
        if (digest) {
          aUser.auths.push(digest);
        }

        // aUser.markModified('strategies');
        // aUser.markModified('auths');
        aUser.save(function (aErr, aUser) {
          aDone(aErr, aUser);
          return;
        });
      } else {
        // The user was authenticated
        aDone(null, aUser);
        return;
      }
    }
  );
};
